﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ConfeccionesJR.Entites;
using ConfeccionesJR.Repository;
using Microsoft.Practices.Unity;

namespace ConfeccionesJR.BussinesLogic
{
    public class ProformaBL : IProformaBL
    {
        [Dependency]
        public  IProformaRepository proformaRepository { get; set; }

        [Dependency]
        public IProductoRepository productoRepository { get; set; }

        [Dependency]
        public  IDetalleProformaRepository detProformaRepository { get; set; }

        [Dependency]
        public IUnidadMedidaRepository undRepository { get; set; }

        [Dependency]
        public IMaterialRepository materialRepository { get; set; }

        public List<PROFORMA> GetAllFromProformasByCriterio(string criterio)
        {
            return proformaRepository.GetAllFromProformasByCriterio(criterio);
        }
        public PROFORMA GetFromProformaByID(int id)
        {
            return proformaRepository.GetProformaById(id);
        }

        public void AddProforma(PROFORMA proforma)
        {
            var msg = "";
            var ok = proforma.Validate(out msg);
            if (ok)
            {
                ValidarStock(proforma);

                proformaRepository.AddProforma(proforma);

            }
            else
            {
                throw new Exception(msg);
            }
        }

        public void UpdateProforma(PROFORMA proforma)
        {
            var msg = "";
            var ok = proforma.Validate(out msg);
            if (ok)
            {
                ValidarStock(proforma);

                proformaRepository.UpdateProforma(proforma);
            }
            else
            {
                throw new Exception(msg);
            }
        }


        private void ValidarStock(PROFORMA proforma)
        {
            foreach (var itemProfo in proforma.DETALLEPROFORMAs)
            {
                var productoBD = productoRepository.GetFromProductoById(itemProfo.productoId);
                
                var detalleProdBD = detProformaRepository.GetProdFromDetProformaByProdIdAndProformaId(itemProfo.productoId, proforma.Id);

                if (detalleProdBD == null)
                {
                    foreach (var itemPro in productoBD.DETALLE_PRODUCTO)
                    {
                        var matBD = materialRepository.GetFromMaterialById(itemPro.materialId);
                        var undMater = undRepository.GetFromUnidadMedidaById(matBD.unidadMedidaId);

                        if (itemProfo.Cantidad * itemPro.Cantidad > matBD.Stock)
                        {
                            var falta = itemProfo.Cantidad * itemPro.Cantidad - matBD.Stock;

                            throw new Exception(string.Format("Producto : {0} \nNo hay Stock suficiente para el material {1}," + " sólo queda {2} {3} \n Falta comprar {4} {5}", 
                                productoBD.Descripcion, matBD.Descripcion, matBD.Stock, undMater, falta, undMater));
                        }
                    }
                }
                
                
                if (detalleProdBD != null)
                {
                    foreach (var itemProBD in productoBD.DETALLE_PRODUCTO)
                    {
                        var matBD = materialRepository.GetFromMaterialById(itemProBD.materialId);
                        var undMater = undRepository.GetFromUnidadMedidaById(matBD.unidadMedidaId);

                        if (itemProfo.Cantidad * itemProBD.Cantidad > matBD.Stock)
                        {
                            var falta = itemProfo.Cantidad * itemProBD.Cantidad - matBD.Stock;

                            throw new Exception(string.Format("Producto : {0} \nLa cantidad máxima del material {1}," + " es {2} {3} \n Falta comprar {4} {5}",
                                productoBD.Descripcion, matBD.Descripcion, itemProBD.MATERIAL.Stock, undMater, falta, undMater));
                        }
                    }
                }
            }
        }

        public void RemoveProforma(int id)
        {
            proformaRepository.RemoveProforma(id);
        }


        public List<PROFORMA> GetFromProformasbyFechasAndCliente(DateTime? fec1, DateTime? fec2, string cliente)
        {
            return proformaRepository.GetFromProformasbyFechasAndCliente(fec1, fec2, cliente);
        }
    }
}

